/*
 * Copyright (C) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain (a) copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.github.fafaldo.fabtoolbar.component;

import ohos.agp.animation.Animator;
import ohos.agp.animation.AnimatorGroup;
import ohos.agp.animation.AnimatorProperty;
import ohos.agp.animation.AnimatorValue;
import ohos.agp.components.AttrSet;
import ohos.agp.components.DependentLayout;
import ohos.agp.components.DirectionalLayout;
import ohos.agp.components.Image;
import ohos.agp.utils.Point;
import ohos.app.Context;

import com.github.fafaldo.fabtoolbar.utils.AttrValue;

/**
 * FABToolbarLayout
 *
 * @since 2021-07-13
 */
public class FABToolbarLayout extends DependentLayout {
    private static final String TAG = "FABToolbarLayout";

    private static final int DIVISOR = 2;
    private static final int TRANSLATION_X_DIVISOR = 3;
    private static final int TRANSLATION_Y_DIVISOR = 4;

    private int SHOW_ANIM_DURATION = 600;
    private int HIDE_ANIM_DURATION = 600;
    private int HORIZONTAL_MARGIN = 100;
    private int VERTICAL_MARGIN = 100;
    private float fraction = 0.2f;
    private boolean isInit = false;

    private DependentLayout mFabToolbarContainer;
    private Image mFabToolbarFab;
    private DirectionalLayout mFabToolbarToolbar;

    private AnimatorGroup animatorGroup;

    private Point fabPos = new Point();
    private Point fabSize = new Point();

    private Point toolbarPos = new Point();
    private Point toolbarSize = new Point();

    /**
     * FABToolbarLayout
     *
     * @param context Context
     */
    public FABToolbarLayout(Context context) {
        super(context);
    }

    /**
     * FABToolbarLayout
     *
     * @param context Context
     * @param attrSet AttrSet
     */
    public FABToolbarLayout(Context context, AttrSet attrSet) {
        this(context, attrSet, null);
    }

    /**
     * FABToolbarLayout
     *
     * @param context Context
     * @param attrSet AttrSet
     * @param styleName String
     */
    public FABToolbarLayout(Context context, AttrSet attrSet, String styleName) {
        super(context, attrSet, styleName);
        parseAttrs(attrSet);
    }

    private void parseAttrs(AttrSet attrSet) {
        SHOW_ANIM_DURATION = AttrValue.get(attrSet, "showDuration", SHOW_ANIM_DURATION);
        HIDE_ANIM_DURATION = AttrValue.get(attrSet, "hideDuration", HIDE_ANIM_DURATION);

        VERTICAL_MARGIN = AttrValue.getDimension(attrSet, "verticalMargin", VERTICAL_MARGIN);
        HORIZONTAL_MARGIN = AttrValue.getDimension(attrSet, "horizontalMargin", HORIZONTAL_MARGIN);

        fraction = AttrValue.get(attrSet, "fadeInFraction", fraction);
    }

    /**
     * setFabToolbarContainer
     *
     * @param fabToolbarContainer DependentLayout
     */
    public void setFabToolbarContainer(DependentLayout fabToolbarContainer) {
        mFabToolbarContainer = fabToolbarContainer;
    }

    /**
     * setFabToolbarFab
     *
     * @param fabToolbarFab Image
     */
    public void setFabToolbarFab(Image fabToolbarFab) {
        mFabToolbarFab = fabToolbarFab;
    }

    /**
     * setFabToolbarToolbar
     *
     * @param fabToolbarToolbar DirectionalLayout
     */
    public void setFabToolbarToolbar(DirectionalLayout fabToolbarToolbar) {
        mFabToolbarToolbar = fabToolbarToolbar;
    }

    /**
     * 显示底部导航栏
     */
    public void show() {
        animatorGroup = new AnimatorGroup();

        if (mFabToolbarToolbar.getVisibility() == VISIBLE) {
            return;
        }
        if (!isInit) {
            isInit = true;
            int[] fabP = mFabToolbarFab.getLocationOnScreen();
            fabPos.modify(fabP[0], fabP[1]);
            fabSize.modify(mFabToolbarFab.getWidth(), mFabToolbarFab.getHeight());

            int[] pos = mFabToolbarToolbar.getLocationOnScreen();
            toolbarPos.modify(pos[0], pos[1]);
            toolbarSize.modify(mFabToolbarToolbar.getWidth(), mFabToolbarToolbar.getHeight());
        }
        AnimatorValue animatorValue = new AnimatorValue();
        animatorValue.setDuration(SHOW_ANIM_DURATION / DIVISOR);
        animatorValue.setDelay(0);
        animatorValue.setLoopedCount(0);
        animatorValue.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
            @Override
            public void onUpdate(AnimatorValue animatorValue, float value) {
                mFabToolbarContainer.setTranslation(-toolbarSize.getPointX() * value / TRANSLATION_X_DIVISOR,
                    ((toolbarPos.getPointY() - fabPos.getPointY())
                        + (toolbarSize.getPointY() / TRANSLATION_Y_DIVISOR)) * value);
            }
        });

        AnimatorProperty animatorProperty = mFabToolbarToolbar.createAnimatorProperty();
        mFabToolbarToolbar.setScale(0f, 0f);
        mFabToolbarToolbar.setVisibility(VISIBLE);
        animatorProperty.scaleX(1);
        animatorProperty.scaleY(1);
        animatorProperty.setDuration(SHOW_ANIM_DURATION / DIVISOR);
        animatorGroup.runSerially(animatorValue, animatorProperty);
        animatorGroup.start();
    }

    /**
     * 隐藏底部导航栏
     */
    public void hide() {
        animatorGroup = new AnimatorGroup();
        animatorGroup.setStateChangedListener(new Animator.StateChangedListener() {
            @Override
            public void onStart(Animator animator) {
            }

            @Override
            public void onStop(Animator animator) {
                mFabToolbarToolbar.setVisibility(INVISIBLE);
            }

            @Override
            public void onCancel(Animator animator) {
                mFabToolbarToolbar.setVisibility(INVISIBLE);
            }

            @Override
            public void onEnd(Animator animator) {
                mFabToolbarToolbar.setVisibility(INVISIBLE);
            }

            @Override
            public void onPause(Animator animator) {
            }

            @Override
            public void onResume(Animator animator) {
            }
        });

        AnimatorValue animatorValue = new AnimatorValue();
        animatorValue.setDuration(HIDE_ANIM_DURATION / DIVISOR);
        animatorValue.setDelay(0);
        animatorValue.setLoopedCount(0);
        animatorValue.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
            @Override
            public void onUpdate(AnimatorValue animatorValue, float value) {
                mFabToolbarContainer.setTranslation(0, 0);
            }
        });

        AnimatorProperty animatorProperty = mFabToolbarToolbar.createAnimatorProperty();
        mFabToolbarToolbar.setScale(1f, 1f);
        mFabToolbarToolbar.setVisibility(VISIBLE);
        animatorProperty.scaleX(0f);
        animatorProperty.scaleY(0f);
        animatorProperty.setDuration(HIDE_ANIM_DURATION / DIVISOR);
        animatorGroup.runSerially(animatorProperty, animatorValue);
        animatorGroup.start();
    }
}
